/***********************************************************************************
 * 文件名： mcu_timer.h
 * 版本： 1
 * 说明：
 * 		NY8 的定时器外设驱动。使用说明见头文件。在 ny8_driver_config.h 文件中可配置初始状态。
 * 修改记录：
 * 	2022/04/14: 初版。 刘言。
***********************************************************************************/
#ifndef _MCU_TIMER_H_
#define _MCU_TIMER_H_

#include "mcu.h"

// TIM0 ----------------------------------------------------------------------------

// TIM0初始化
// 初始化后立即运行
// 在配置文件中统一配置中断使能状态，调用 Mcu_Init 后生效。
// TIM0不支持自动重装载，可以调用 Tim0_Reload 进行手动重装载。
#define Tim0_Init() \
{\
    /*PCON1 &= 0xFE; */\
    T0MD = (TIM0_PS << 0) \
        |(TIM0_PAS << 3) \
        |(TIM0_CLK_SOURCE << 5) \
        |(TIM0_LCK << 7); \
    TMR0 = 256 - TIM0_CYCLE; \
    /*PCON1 |= TIM0_EN; */\
}

// 重装载，一般在中断中调用，用于周期定时
#define Tim0_Reload()   \
{\
    TMR0 = 256 - TIM0_CYCLE;\
}

// 获取 TIM0 的中断标志
#define Tim0_GetIntFlag()   T0IF

// 清除 TIM0 的中断标志
#define Tim0_ClrIntFlag()   T0IF=0


// TIM1 ----------------------------------------------------------------------------

// TIM1参数检查
#if (TIM1_LEN == 8)
    #if (TIM1_CYCLE > 255) || (TIM1_PWM > 255)
        #error "TIM1 8位模式下 TIM1_CYCLE 、 TIM1_PWM 最大255。"
    #endif
#else
    #if (TIM1_CYCLE > 1023) || (TIM1_PWM > 1023)
        #error "TIM1 8位模式下 TIM1_CYCLE 、 TIM1_PWM 最大1023。"
    #endif
#endif

// TIM1初始化
// 在配置文件中统一初始化中断使能状态，调用 Mcu_Init 后生效。
// 支持自动重装载。当T1EN=0 时， 定时器 1 重载缓存寄存器会立即写入定时器 1。 当T1EN=1 时， 会等到定时器 1 下溢后，定时器 1 重载缓存寄存器才会写入定时器 1。 
#define Tim1_Init() \
{\
    TMRH = (((u16)TIM1_PWM >> 8) << 0) \
        |(((u16)TIM2_PWM >> 8) << 2) \
        |(((u16)TIM1_CYCLE >> 8) << 4) \
        |(((u16)TIM2_CYCLE >> 8) << 6); \
    TMR1 = (TIM1_CYCLE & 0X00FF); \
    PWM1DUTY = (TIM1_PWM & 0X00FF); \
    T1CR2 = (TIM1_PS << 0) \
        |(TIM1_CLK_SOURCE << 5); \
    T1CR1 = (TIM1_EN << 0) \
        |(1 << 1) /*固定开启自动重装载*/\
        |(TIM1_ONE << 2) \
        |(TIM1_PWMOAL << 6) \
        |(TIM1_PWMOEN << 7); \
}

// 必须开启定时器中断才有效
#define Tim1_GetIntFlag()   T1IF
#define Tim1_ClrIntFlag()   T1IF = 0

#if (TIM1_LEN == 8)
    // 获取计数值
    #define Tim1_GetValue()     TMR1
    // 设置计数值。定时器运行时仅写入缓冲，溢出后更新。定时器未运行会直接写入。
    #define Tim1_SetValue(u8_value) TMR1 = u8_value
#else
    // 获取计数值
    #define Tim1_GetValue()     (u16)(((u16)(TMRH & 0X30) << 4) | TMR1)
    // 设置计数值。定时器运行时仅写入缓冲，溢出后更新。定时器未运行会直接写入。不可以超过1023。
    #define Tim1_SetValue(u16_value) \
    {\
        TMRH &= 0xCF;\
        TMRH |= ((u8)(u16_value >> 8) << 4);\
        TMR1 = (u8)u16_value;\
    }
#endif

// 启动TIM1
#define Tim1_Run()          T1CR1 |= 0x01

// 停止TIM1
#define Tim1_Stop()         T1CR1 &= 0xFE

// 设置 TIM1 的时钟
// 0X00 ~ 0X08 分别为FINST的2、4、8、16、32、64、128、256、1分频。
// 0X20 ~ 0X28 分别为EX_CKI0的2、4、8、16、32、64、128、256、1分频。
#define Tim1_SetClock(c)    T1CR2 = c

// TIM2 ----------------------------------------------------------------------------

// TIM2参数检查
#if (TIM2_LEN == 8)
    #if (TIM2_CYCLE > 255) || (TIM2_PWM > 255)
        #error "TIM2 8位模式下 TIM2_CYCLE 、 TIM2_PWM 最大255。"
    #endif
#else
    #if (TIM2_CYCLE > 1023) || (TIM2_PWM > 1023)
        #error "TIM2 8位模式下 TIM2_CYCLE 、 TIM2_PWM 最大1023。"
    #endif
#endif

// TIM2初始化
// 在配置文件中统一初始化中断使能状态，调用 Mcu_Init 后生效。
// 支持自动重装载。当T2EN=0 时， 定时器 2 重载缓存寄存器会立即写入定时器 2。 当T2EN=1 时， 会等到定时器 2 下溢后，定时器 2 重载缓存寄存器才会写入定时器 2。 
#define Tim2_Init() \
{\
    TMRH = (((u16)TIM1_PWM >> 8) << 0) \
        |(((u16)TIM2_PWM >> 8) << 2) \
        |(((u16)TIM1_CYCLE >> 8) << 4) \
        |(((u16)TIM2_CYCLE >> 8) << 6); \
    TMR2 = (TIM2_CYCLE & 0X00FF); \
    PWM2DUTY = (TIM2_PWM & 0X00FF); \
    T2CR2 = (TIM2_PS << 0) \
        |(TIM2_CLK_SOURCE << 5); \
    T2CR1 = (TIM2_EN << 0) \
        |(1 << 1) \
        |(TIM2_ONE << 2) \
        |(TIM2_PWMOAL << 6) \
        |(TIM2_PWMOEN << 7); \
}

// 必须开启定时器中断才有效
#define Tim2_GetIntFlag()   T2IF
#define Tim2_ClrIntFlag()   T2IF = 0

#if (TIM2_LEN == 8)
    // 获取计数值
    #define Tim2_GetValue()     TMR2
    // 设置计数值。定时器运行时仅写入缓冲，溢出后更新。定时器未运行会直接写入。
    #define Tim2_SetValue(u8_value) TMR2 = u8_value
#else
    // 获取计数值
    #define Tim2_GetValue()     (u16)(((u16)(TMRH & 0XC0) << 2) | TMR2)
    // 设置计数值。定时器运行时仅写入缓冲，溢出后更新。定时器未运行会直接写入。不可以超过1023。
    #define Tim2_SetValue(u16_value) \
    {\
        TMRH &= 0x3F;\
        TMRH |= ((u8)(u16_value >> 8) << 6);\
        TMR2 = (u8)u16_value;\
    }
#endif

// 启动TIM2
#define Tim2_Run()          T2CR1 |= 0x01

// 停止TIM2
#define Tim2_Stop()         T2CR1 &= 0xFE

// 设置 TIM2 的时钟
// 0X00 ~ 0X08 分别为FINST的2、4、8、16、32、64、128、256、1分频。
// 0X20 ~ 0X28 分别为EX_CKI1的2、4、8、16、32、64、128、256、1分频。
#define Tim2_SetClock(c)    T2CR2 = c

// TIM3 ----------------------------------------------------------------------------

// TIM3参数检查
#if (TIM3_LEN == 8)
    #if (TIM3_CYCLE > 255) || (TIM3_PWM > 255)
        #error "TIM3 8位模式下 TIM3_CYCLE 、 TIM3_PWM 最大255。"
    #endif
#else
    #if (TIM3_CYCLE > 1023) || (TIM3_PWM > 1023)
        #error "TIM3 8位模式下 TIM3_CYCLE 、 TIM3_PWM 最大1023。"
    #endif
#endif

// TIM3初始化
// 在配置文件中统一初始化中断使能状态，调用 Mcu_Init 后生效。
// 支持自动重装载。当T3EN=0 时， 定时器 3 重载缓存寄存器会立即写入定时器 3。 当T3EN=1 时， 会等到定时器 3 下溢后，定时器 3 重载缓存寄存器才会写入定时器 3。 
#define Tim3_Init() \
{\
    TM3RH = (((u16)TIM3_PWM >> 8) << 0) \
        |(((u16)TIM3_CYCLE >> 8) << 4); \
    TMR3 = (TIM3_CYCLE & 0X00FF); \
    PWM2DUTY = (TIM3_PWM & 0X00FF); \
    T3CR2 = (TIM3_PS << 0) \
        |(TIM3_CLK_SOURCE << 5); \
    T3CR1 = (TIM3_EN << 0) \
        |(1 << 1) \
        |(TIM3_ONE << 2) \
        |(TIM3_PWMOAL << 6) \
        |(TIM3_PWMOEN << 7); \
}

// 必须开启定时器中断才有效
#define Tim3_GetIntFlag()   T3IF
#define Tim3_ClrIntFlag()   T3IF = 0

#if (TIM3_LEN == 8)
    // 获取计数值
    #define Tim3_GetValue()     TMR3
    // 设置计数值。定时器运行时仅写入缓冲，溢出后更新。定时器未运行会直接写入。
    #define Tim3_SetValue(u8_value) TMR3 = u8_value
#else
    // 获取计数值
    #define Tim3_GetValue()     (u16)(((u16)(TM3RH & 0X30) << 4) | TMR3)
    // 设置计数值。定时器运行时仅写入缓冲，溢出后更新。定时器未运行会直接写入。不可以超过1023。
    #define Tim3_SetValue(u16_value) \
    {\
        TM3RH &= 0xCF;\
        TM3RH |= ((u8)(u16_value >> 8) << 4);\
        TMR3 = (u8)u16_value;\
    }
#endif

// 启动TIM3
#define Tim3_Run()          T3CR1 |= 0x01

// 停止TIM3
#define Tim3_Stop()         T3CR1 &= 0xFE

// 设置 TIM3 的时钟
// 0X00 ~ 0X08 分别为FINST的2、4、8、16、32、64、128、256、1分频。
// 0X20 ~ 0X28 分别为EX_CKI1的2、4、8、16、32、64、128、256、1分频。
#define Tim3_SetClock(c)    T3CR2 = c

#endif



